<?php
namespace App\Services\Base\Auth;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use App\Core\Entity\Auth\UserEntity as AuthUserEntity;
use App\Exceptions\Response\Service\ServiceException;
use App\Exceptions\Response\Service\ServiceCode;
use App\Models\Base\UserModel;
use App\Models\Auth\TokenModel as AuthTokenModel;

class UserService
{

    /**
     * 制作用户密码
     *
     * @param string $password            
     * @return string
     */
    public function makeUserPassword($password)
    {
        return Hash::make($password);
    }

    /**
     * 验证用户密码
     *
     * @param array $user            
     * @param string $password            
     * @throws ServiceException
     * @return $this
     */
    public function verifyUserPassword($user, $password)
    {
        if (! Hash::check($password, $user['password'])) {
            throw new ServiceException(ServiceCode::SERVICE_PARAM_INVALID_PASSWORD);
        }
        return $this;
    }

    /**
     * 验证用户状态
     *
     * @param array $user            
     * @throws ServiceException
     * @return $this
     */
    public function verifyUserStatus($user)
    {
        if ($user['status'] == UserModel::STATUS_DISABLE) {
            throw new ServiceException(ServiceCode::SERVICE_DISABLE_USER);
        }
        return $this;
    }

    /**
     * 验证是否为超级管理员（是则抛出异常）
     *
     * @param array $user            
     * @throws ServiceException
     * @return $this
     */
    public function verifyUserIsSuperAdmin($user)
    {
        if ($user['is_super_admin'] == UserModel::SUPER_ADMIN_TRUE) {
            throw new ServiceException(ServiceCode::SERVICE_SUPER_ADMIN_AUTH);
        }
        return $this;
    }

    /**
     * 更新用户数据
     *
     * @param int $id            
     * @param array $data            
     * @throws ServiceException
     * @return boolean
     */
    public function update($id, $data)
    {
        if (! ($status = UserModel::update($id, $data))) {
            throw new ServiceException(ServiceCode::SERVICE_ACTION_SAVE_ERROR);
        }
        
        return (boolean) $status;
    }

    /**
     * 更新用户密码
     *
     * @param int $id            
     * @param string $password            
     * @throws ServiceException
     * @return boolean
     */
    public function updatePassword($id, $password)
    {
        $data['password'] = $this->makeUserPassword($password);
        
        if (! ($status = UserModel::update($id, $data))) {
            throw new ServiceException(ServiceCode::SERVICE_ACTION_SAVE_ERROR);
        }
        
        return (boolean) $status;
    }

    /**
     * 制作用户 auth 数据
     *
     * @param array $user            
     * @return array
     */
    private function makeAuthData(array $user = [])
    {
        return collect($user)->only('user_id', 'user_type', 'token')->all();
    }

    /**
     * 获取用户数据
     *
     * @param string $token            
     * @return array
     */
    public function getUserToken($token)
    {
        $user = AuthTokenModel::findByToken($token)->shift();
        
        return ! empty($user) ? $this->makeAuthData($user) : [];
    }

    /**
     * 同步用户数据到 auth，并持久化用户token
     *
     * @param AuthUserEntity $userEntity            
     * @param array $user            
     * @return $this
     */
    public function synAuthData(AuthUserEntity $userEntity, array $user = [])
    {
        // 可以查询用户完整数据，demo暂不查询
        $data = $this->makeAuthData($user);
        
        // 持久化用户token
        DB::transaction(function () use ($data) {
            // 删除旧数据
            AuthTokenModel::destroyByUser($data['user_id'], $data['user_type']);
            // 插入新数据
            AuthTokenModel::create($data);
        });
        
        // 同步用户数据到 auth
        $userEntity->setAuthToken($data['token'])
            ->initData($data)
            ->save();
        
        return $this;
    }

    /**
     * 清除 auth 数据和持久化数据
     *
     * @param AuthUserEntity $userEntity            
     * @return $this
     */
    public function destroyAuthData(AuthUserEntity $userEntity)
    {
        // 清除持久化token
        AuthTokenModel::destroyByToken($userEntity->getAuthToken());
        
        // 清除用户数据到 auth
        $userEntity->setAuthToken(null)
            ->initData([])
            ->save();
        
        return $this;
    }
}